/**
 * $Id$ Copyright 2009-2012 Oak Pacific Interactive. All rights reserved.
 */
package com.shuqi.model.manager;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.content.Context;
import android.text.TextUtils;
import android.widget.Toast;

import com.shuqi.application.ShuqiApplication;
import com.shuqi.common.Constant;
import com.shuqi.common.utils.Util;
import com.shuqi.database.dao.impl.BookCataLogDao;
import com.shuqi.database.dao.impl.BookInfoDao;
import com.shuqi.database.dao.impl.BookMarkInfoDao;
import com.shuqi.database.model.BookCataLog;
import com.shuqi.database.model.BookInfo;
import com.shuqi.database.model.BookMarkInfo;

/**
 * 
 * 限免书籍下载管理类，下载章节和处理回调事件
 * 
 * @author <a href="mailto:">yaozhen</a>
 * @version 2014-3-19上午10:37:55
 * 
 */
public class FreeBookDownloadManager {

    /** 下载线程池 */
    private ExecutorService mThreadPool;

    private static FreeBookDownloadManager mInstance;

    private List<FreeBookDownStateListener> mDownloadListenerList;

    private Hashtable<String, FreeBookDownLoadTask> mDownloadMap;
    private Toast toast;

    /**
     * 定义下载的常量,给BookMarkInfo, BookCover页面, 离线书籍下载页面使用
     * 
     */
    public static class DownConstant {

        /** 无需下载 */
        public static final int STATE_NONE = 0;

        /** 等待下载 */
        public static final int STATE_READY = 1;

        /** 正在下载 */
        public static final int STATE_DOWNLOADING = 2;

        /** 下载失败 */
        public static final int STATE_ERROR = 3;

        /** 完成下载 */
        public static final int STATE_FINISH = 4;
        
    }

    /**
     * 下载状态监听接口
     * 
     * @author
     * 
     */
    public static interface FreeBookDownStateListener {
        void updateDownState(String uid, String bid, int state, int downloadChapterCount,
                int totalChapterCount);
    }

    private FreeBookDownloadManager() {
        mThreadPool = Executors.newFixedThreadPool(3);
        mDownloadListenerList = new ArrayList<FreeBookDownStateListener>();
        mDownloadMap = new Hashtable<String, FreeBookDownLoadTask>();
    }

    public static synchronized FreeBookDownloadManager getInstance() {
        if (mInstance == null) {
            mInstance = new FreeBookDownloadManager();
        }
        return mInstance;
    }

    public void finishTask() {
        if (mDownloadMap != null) {
            for (FreeBookDownLoadTask dlTask : mDownloadMap.values()) {
                if (dlTask != null) {
                    dlTask.setForceStopRunable(true);
                }
            }
        }
    }

    /**
     * 
     * 注册下载状态监听
     * 
     * @param listener
     */
    public void registerDownStateListener(FreeBookDownStateListener listener) {
        if (!mDownloadListenerList.contains(listener)) {
            mDownloadListenerList.add(listener);
        }
    }

    /**
     * 
     * 取消注册状态监听
     * 
     * @param listener
     */
    public void unRegisterDownStateListener(FreeBookDownStateListener listener) {
        if (mDownloadListenerList.contains(listener)) {
            mDownloadListenerList.remove(listener);
        }
    }


    /**
     * 下载限免书籍
     * 
     * @param bookId
     * @param uid
     * @param curCid
     */
    public boolean downloadBook(Context context, String bookId, String uid, String curCid,
            boolean needSaveBookMark) {
        if (TextUtils.isEmpty(uid) || TextUtils.isEmpty(bookId)) {
            return false;
        }
        String downKey = uid + "_" + bookId;
        if (mDownloadMap.containsKey(downKey)) {
            return false;
        }

        // 获取书籍信息,判断是否需要下载
        BookInfo bookInfo = BookInfoDao.getInstance().getBookInfo(null, bookId, uid);
        if (bookInfo == null) {
            return false;
        }
        int downCount = bookInfo.getBookDownCount();
        int totalCount = bookInfo.getBookMaxOid();
        // 之前的逻辑
        if (totalCount > 0 && totalCount == downCount) {
            notifyDownloadState(DownConstant.STATE_NONE, uid, bookId, downCount, totalCount);
            return false;
        }

        if (!Util.isNetworkConnected(context)) {
            if (toast == null) {
                toast = Toast.makeText(context, "连接失败，请检查您的网络", Toast.LENGTH_SHORT);
            } else {
                toast.setText("连接失败，请检查您的网络");
            }
            toast.show();
            return false;
        }

        // 需要下载书籍
        FreeBookDownloadModel model = new FreeBookDownloadModel(uid, bookId, curCid);
        // 开始下载的时候存一个书签
        if (needSaveBookMark) {
            saveBookMark(bookInfo, uid, curCid);
        }
        // 添加下载任务
        addBookDownLoadTask(model, downCount > 0 ? downCount : 0, totalCount > 0 ? totalCount : 0);
        return true;
    }

    // /**
    // * 释放资源
    // */
    // public void release() {
    // if (mThreadPool != null) {
    // mThreadPool.shutdownNow();
    // }
    // }

    /**
     * 删除下载
     */
    public void delDownTask(String uid, String bookId) {
        String downKey = uid + "_" + bookId;
        if (mDownloadMap.containsKey(downKey)) {
            mDownloadMap.remove(downKey);
        }
    }

    /**
     * 保存书签
     * 
     * @param bookInfo
     * @param uid
     * @param cid
     */
    private void saveBookMark(BookInfo bookInfo, String uid, String cid) {
        if (bookInfo == null) {
            return;
        }
        // 判断是否存在书签
        BookMarkInfo markInfo =
                BookMarkInfoDao.getInstance().getBookMark(null, bookInfo.getBookId(), uid,
                        BookMarkInfo.TYPE_NEW_PAY_BOOKMARK);
        if (markInfo == null) {
            markInfo = new BookMarkInfo();
        }
        // 准备书签
        markInfo.setBookId(bookInfo.getBookId());
        markInfo.setUserId(uid);
        markInfo.setDownloadFlag(DownConstant.STATE_READY);// 正在下载
        String chapterId = markInfo.getChapterId();
        if (TextUtils.isEmpty(chapterId)) {
            markInfo.setChapterId(cid);
        }
        markInfo.setPayMode(Constant.PAYMODE_FREE + "");
        markInfo.setDownCount(bookInfo.getBookDownCount() > 0 ? bookInfo.getBookDownCount() : 0);
        markInfo.setBookType(BookMarkInfo.TYPE_NEW_PAY_BOOKMARK);
        markInfo.setTotalChapter(bookInfo.getBookMaxOid() > 0 ? bookInfo.getBookMaxOid() : 0);
        markInfo.setBookCoverImgUrl(bookInfo.getBookCoverImgUrl());
        markInfo.setBookName(bookInfo.getBookName());
        BookMarkInfoDao.getInstance().saveBookMark(markInfo);
    }

    /**
     * 增加新的downloadTask
     * 
     * @param bookInfo
     */
    private void addBookDownLoadTask(FreeBookDownloadModel model, int downCount, int totalCount) {
        FreeBookDownLoadTask downLoadTask = new FreeBookDownLoadTask(model);
        mDownloadMap.put(model.getKey(), downLoadTask);
        model.setDownState(DownConstant.STATE_READY);
        notifyDownloadState(DownConstant.STATE_READY, model.getUid(), model.getBookId(), downCount,
                totalCount);
        mThreadPool.execute(downLoadTask);
    }

    /**
     * 
     * @param state
     * @param uid
     * @param bookId
     * @param downloadCount
     * @param totalCount
     */
    private void notifyDownloadState(int state, String uid, String bookId, int downloadCount,
            int totalCount) {
        for (FreeBookDownStateListener l : mDownloadListenerList) {
            l.updateDownState(uid, bookId, state, downloadCount, totalCount);
        }
    }

    /**
     * 更新书签的下载状态
     * 
     * @param bid
     * @param uid
     * @param state
     * @param downCount
     */
    private void updateBookMarkSate(int state, String uid, String bookId, int downloadCount) {
        BookMarkInfoDao.getInstance().updateBookMarkDownloadState(uid, bookId,
                BookMarkInfo.TYPE_NEW_PAY_BOOKMARK, state, downloadCount);
    }

    /**
     * 根据uid和bookId查询当前是否缓存了下载
     * 
     * @param uid
     * @param bookId
     * @return 返回书籍的下载状态
     */
    public int getDownloadShuqiBookState(String uid, String bookId) {
        if (TextUtils.isEmpty(uid)|| TextUtils.isEmpty(bookId)) {
            return DownConstant.STATE_ERROR;
        }

        String downKey = getDownId(uid, bookId);

        if (mDownloadMap.containsKey(downKey)) {
            int state = mDownloadMap.get(downKey).getDownState();
            return state;
        }

        return DownConstant.STATE_ERROR;
    }

    /**
     * 返回有uid和bookId组合成的主键
     * 
     * @param uid
     * @param bookId
     * @return
     */
    private String getDownId(String uid, String bookId) {
        return uid + "_" + bookId;
    }


    /**
     * 离线书籍下载
     * 
     * @author
     * 
     */
    private class FreeBookDownLoadTask implements Runnable {

        private FreeBookDownloadModel mBookInfo;
        private boolean isForceStopRunable = false;

        public boolean isForceStopRunable() {
            return isForceStopRunable;
        }

        public void setForceStopRunable(boolean isForceStopRunable) {
            this.isForceStopRunable = isForceStopRunable;
        }

        public FreeBookDownLoadTask(FreeBookDownloadModel info) {
            mBookInfo = info;
        }

        public int getDownState() {
            if (mBookInfo != null) {
                return mBookInfo.getDownState();
            }
            return DownConstant.STATE_ERROR;
        }


        @Override
        public void run() {
            download();
            removeDownLoad();
        }

        private boolean isNeedDownLoad() {
            if (mDownloadMap != null) {
                return mDownloadMap.containsKey(mBookInfo.getKey());
            }
            return false;
        }

        private void removeDownLoad() {
            if (mDownloadMap != null) {
                mDownloadMap.remove(mBookInfo.getKey());
            }
        }

        private void download() {
            if (mBookInfo == null || !isNeedDownLoad()) {
                return;
            }

            final String uid = mBookInfo.getUid();
            final String bid = mBookInfo.getBookId();

            // 获取总章节
            List<BookCataLog> catalogList = getCatalogList(uid, bid);

            // 获取信息完整的书籍信息
            BookInfo bookInfo = BookInfoDao.getInstance().getBookInfo(null, bid, uid);


            // 判断是否强制停止下载
            if (isForceStopRunable) {
                notifyDownloadState(DownConstant.STATE_ERROR, uid, bid, 0, 0);
                updateBookMarkSate(DownConstant.STATE_ERROR, uid, bid, bookInfo.getBookDownCount());
                return;
            }

            // 判断目录是否正确获取信息
            if (bookInfo == null || bookInfo.getBookMaxOid() <= 0 || catalogList == null
                    || catalogList.size() == 0) {
                notifyDownloadState(DownConstant.STATE_ERROR, uid, bid, 0, 0);
                updateBookMarkSate(DownConstant.STATE_ERROR, uid, bid, bookInfo.getBookDownCount());
                return;
            }

            // 更新信息
            int totalCount = bookInfo.getBookMaxOid();
            int downloadCount =
                    (int) BookCataLogDao.getInstance().getChapterDownLoadCount(uid, bid);

            // 开始下载书籍,更新状态
            notifyDownloadState(DownConstant.STATE_DOWNLOADING, uid, bid, downloadCount, totalCount);
            mBookInfo.setDownState(DownConstant.STATE_DOWNLOADING);

            // 更新书签的总章节数
            BookMarkInfoDao.getInstance().updateBookMarkDownloadTotalCount(uid, bid,
                    BookMarkInfo.TYPE_NEW_PAY_BOOKMARK, DownConstant.STATE_DOWNLOADING, totalCount);

            // 根据目录判断需要下载的章节
            List<BookCataLog> needDownloadCatalogList = new ArrayList<BookCataLog>();
            for (BookCataLog bookCataLog : catalogList) {
                if (bookCataLog.getDownloadState() == BookCataLog.UN_DOWN) {
                    needDownloadCatalogList.add(bookCataLog);
                }
            }
            catalogList.clear();
            int size = needDownloadCatalogList.size();
            if (size == 0) {
                // 下载完成
                update(uid, bid, totalCount, totalCount, DownConstant.STATE_FINISH);
                return;
            }

            // 遍历需要下载的章节
            for (BookCataLog bookCataLog : needDownloadCatalogList) {
                if (!isNeedDownLoad()) {
                    break;
                }
                String downloadContent = null;
                // 下载章节内容
                List<String> chapterContents =
                        DownLoadBookManager.loadPayChapterContent(ShuqiApplication.getContext(),
                                bookCataLog.getChapterContentUrl());
                if (chapterContents != null && chapterContents.size() > 0) {
                    downloadContent = chapterContents.get(0);
                }
                if (TextUtils.isEmpty(downloadContent)) {
                    break;
                }

                if (isForceStopRunable) {
                    // 强行退出下载线程
                    break;
                }

                String cid = bookCataLog.getChapterId();
                if (!isNeedDownLoad()) {
                    break;
                }
                // 写文件
                DownLoadBookManager.writeChapterFile(null, bid, uid, cid, downloadContent);

                // 更新目录数据库
                BookCataLogDao.getInstance().updateCatalogToDown(bid, null, uid, cid);

                // 更新书籍数据库
                int downCount =
                        (int) BookCataLogDao.getInstance().getChapterDownLoadCount(uid, bid);

                update(uid, bid, downCount, totalCount, DownConstant.STATE_DOWNLOADING);
            }
            // 跳出下载目录, 判断是否下载成功
            int downCount = (int) BookCataLogDao.getInstance().getChapterDownLoadCount(uid, bid);
            int state =
                    (downCount > 0 && totalCount > 0 && downCount == totalCount) ? DownConstant.STATE_FINISH
                            : DownConstant.STATE_ERROR;
            update(uid, bid, downCount, totalCount, state);
        }

        private void update(String uid, String bid, int downloadCount, int totalCount, int state) {
            // 更新书籍数据库
            BookInfoDao.getInstance().updateDowncount(uid, bid, downloadCount);
            // 更新书签数据库
            updateBookMarkSate(state, uid, bid, downloadCount);
            // 回调下载状态
            notifyDownloadState(state, uid, bid, downloadCount, totalCount);
        }

        /**
         * 获取书籍目录
         * 
         * @param uid
         * @param bid
         * @return
         */
        private List<BookCataLog> getCatalogList(String uid, String bid) {
            List<BookCataLog> catalogList = null;
            catalogList = BookCataLogDao.getInstance().getAllChapterCatalog(uid, bid, "");
            if (catalogList == null || catalogList.size() == 0) {
                BookCatalogManager.syncDownloadCatalog(bid, "", uid,
                        BookMarkInfo.TYPE_NEW_PAY_BOOKMARK, null);
                catalogList = BookCataLogDao.getInstance().getAllChapterCatalog(uid, bid, "");
            }
            return catalogList;
        }
    }


    static class FreeBookDownloadModel {
        private String uid;

        private String bookId;

        private String chapterId;

        private int downState;

        public FreeBookDownloadModel(String uid, String bookId, String chatperId) {
            this.uid = uid;
            this.bookId = bookId;
            this.chapterId = chatperId;
        }

        public String getUid() {
            return uid;
        }

        public String getBookId() {
            return bookId;
        }

        public String getChapterId() {
            return chapterId;
        }

        public int getDownState() {
            return downState;
        }

        public void setUid(String uid) {
            this.uid = uid;
        }

        public void setBookId(String bookId) {
            this.bookId = bookId;
        }

        public void setChapterId(String chapterId) {
            this.chapterId = chapterId;
        }

        public void setDownState(int downState) {
            this.downState = downState;
        }

        public String getKey() {
            return uid + "_" + bookId;
        }
    }
}
